package com.example.apiproxydemo.core.config;

import cn.hutool.core.util.StrUtil;
import com.example.apiproxydemo.core.model.上游服务;
import com.example.apiproxydemo.core.model.开放api接口;
import com.example.apiproxydemo.core.model.路由;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.util.JSONPObject;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.sql.SQLOutput;
import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static org.springframework.web.reactive.function.server.RequestPredicates.*;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;

/**
 * @Description TODO
 * @Author zhoupan
 * @Date 2022/2/21 12:03
 */
@Component
public class 代理设置缓存 {


    public static LinkedHashMap<String, 开放api接口> 开放接口缓存 = new LinkedHashMap<>();

//    public static Map<String, 路由>  静态路由 = new LinkedHashMap<>();

    public static Map<String, 路由>  路由缓存 = new LinkedHashMap<>();

    public static Map<String, 上游服务>  服务缓存 = new LinkedHashMap<>();

    private static ConcurrentMap<String,Boolean> f  = new ConcurrentHashMap() ;


    static {

        f.put("f",false);
    }

    /**
     * 用来操作缓存的接口
     * @return
     */
    @Bean
    public RouterFunction<ServerResponse> 测试缓存更新接口() {
            return route(POST("/test/api").and(accept(MediaType.APPLICATION_JSON)), 代理设置缓存::更新api列表)
                    .andRoute(DELETE("/test/api").and(accept(MediaType.APPLICATION_JSON)), 代理设置缓存::移除api列表)
                    .andRoute(POST("/test/route").and(accept(MediaType.APPLICATION_JSON)), 代理设置缓存::更新路由)
                    .andRoute(DELETE("/test/route").and(accept(MediaType.APPLICATION_JSON)), 代理设置缓存::移除路由)
                    .andRoute(POST("/test/service").and(accept(MediaType.APPLICATION_JSON)), 代理设置缓存::更新服务)
                    .andRoute(DELETE("/test/service").and(accept(MediaType.APPLICATION_JSON)), 代理设置缓存::移除服务)
                    .andRoute(GET("/test/api/list").and(accept(MediaType.APPLICATION_JSON)), 代理设置缓存::获取所有Api列表);
    }
    public static Mono<ServerResponse> 更新路由(ServerRequest request) {
        Mono<路由> 要更新路由=request.bodyToMono(路由.class);
        return ServerResponse.ok().body(要更新路由.doOnNext(result -> {
            路由缓存.put(result.get前端路由地址(),result);
            f.put("f",true);
        }).map(a->"success"),String.class );
    }
    public static Mono<ServerResponse> 移除路由(ServerRequest request) {
        Mono<路由> 要更新路由=request.bodyToMono(路由.class);
        return ServerResponse.ok().body(要更新路由.doOnNext(result -> {
            路由缓存.remove(result.get前端路由地址(),result);
            f.put("f",true);
        }).map(a->"success"),String.class );
    }
    public static Mono<ServerResponse> 更新服务(ServerRequest request) {
        Mono<上游服务> 要更新路由=request.bodyToMono(上游服务.class);
        return ServerResponse.ok().body(要更新路由.doOnNext(result -> {
            服务缓存.put(result.get服务名称(),result);
            f.put("f",true);
        }).map(a->"success"),String.class );
    }
    public static Mono<ServerResponse> 移除服务(ServerRequest request) {
        Mono<上游服务> 要更新路由=request.bodyToMono(上游服务.class);
        return ServerResponse.ok().body(要更新路由.doOnNext(result -> {
            服务缓存.remove(result.get服务名称(),result);
            f.put("f",true);
        }).map(a->"success"),String.class );
    }
    public static Mono<ServerResponse> 移除api列表(ServerRequest request) {

        Mono<开放api接口> 要更新接口=request.bodyToMono(开放api接口.class);
        return ServerResponse.ok().body(要更新接口.doOnNext(result -> {
            开放接口缓存.remove(result.get访问路径());
            f.put("f",true);
        }).map(a->"success"),String.class );
    }
    public static Mono<ServerResponse> 更新api列表(ServerRequest request) {

        Mono<开放api接口> 要更新接口=request.bodyToMono(开放api接口.class);
        return ServerResponse.ok().body(要更新接口.doOnNext(result -> {
            开放接口缓存.put(result.get访问路径(),result);
            f.put("f",true);
        }),开放api接口.class );
//        return ok().contentType(MediaType.APPLICATION_JSON).body(Mono.just(开放接口缓存), Map.class);
    }
    public static Mono<ServerResponse> 获取所有Api列表(ServerRequest serverRequest) {
        Flux<Map<String, 开放api接口>> apiMap = Flux.interval(Duration.ofSeconds(1))
                .filter(a -> {
                    if (代理设置缓存.f.get("f") == true || a == 1L) {
                        f.put("f",false);
                        return true;
                    }
                    return false;
                })
                .map(a -> 开放接口缓存);
        return ServerResponse.ok()
                .contentType(MediaType.TEXT_EVENT_STREAM)
                .body(
                        apiMap.map(a->{
                            LinkedHashMap linkedHashMap = new LinkedHashMap<>(a.size()+1);
                            linkedHashMap.put("msg", StrUtil.format("共有api{}个",a.size()));
                            linkedHashMap.putAll(a);
                            return linkedHashMap;
                        })
                       , LinkedHashMap.class);
    }
}
